import React, { useEffect, useRef, useState } from "react";
import {
  Modal,
  ModalContent,
  ModalHeader,
  ModalBody,
  ModalFooter,
  Button,
  useDisclosure,
  Input,
  Select,
  SelectItem,
  Textarea,
} from "@nextui-org/react";
import { showToast } from "../../toast";
import { useGlobalState, useHttp } from "@/hooks";
import { useRouter } from "next/router";
import ConfigValue from "./configValue";
import { tryParse } from "@/utils/base";

type Props = {
  size?:
    | "xs"
    | "sm"
    | "md"
    | "lg"
    | "xl"
    | "2xl"
    | "3xl"
    | "4xl"
    | "5xl"
    | "full";
  openCallback?: Fn;
  closeCallback?: Fn;
  confirmCallback?: Fn;
  cancelBtnText?: string;
  confirmBtnText?: string;
  triggerBtnText?: string;
  triggerBtnSize?: "sm" | "md" | "lg";
  mode: "create" | "edit";
  configId?: number;
  visible?: boolean;
};

const ConfigModal: React.FC<Props> = ({
  size = "3xl",
  openCallback,
  closeCallback,
  triggerBtnText,
  confirmCallback,
  cancelBtnText,
  confirmBtnText,
  mode,
  configId,
  visible,
  triggerBtnSize = "sm",
}) => {
  const { isOpen, onOpen, onClose } = useDisclosure();
  const [name, setName] = useState("");
  const [introduce, setIntroduce] = useState("");
  const [type, setType] = useState<FieldType>("string");
  const [env, setEnv] = useState("all");
  const [value, setValue] = useState<any>(null);
  const [oldValue, setOldValue] = useState<any>(null);
  const [oldType, setOldType] = useState<any>(undefined);

  const isCreateMode = mode === "create";
  const [isDataReady, setIsDataReady] = useState(isCreateMode);

  const updateValue = (val: any) => {
    // console.log("🚀 ~ 112 updateValue ~ val:", val);
    setValue(val);
  };

  const router = useRouter();
  const { appid: appId } = router.query;

  const resetInputs = () => {
    setName("");
    setIntroduce("");
    setType("string");
    setValue(null);
    setEnv("all");
  };

  const handleOpen = async () => {
    if (openCallback) {
      openCallback();
    }
    onOpen();

    isCreateMode && resetInputs();

    if (!isCreateMode && appId && configId) {
      const res = await http.get(
        `/api/config/detail`,
        { appid: appId, configid: configId },
        { silent: true }
      );
      if (res?.success) {
        setName(res.data.name);
        setIntroduce(res.data.introduce);
        setType(res.data.type);

        let retValue = res.data.value;
        if (["number", "boolean", "array", "object"].includes(res.data.type)) {
          retValue = tryParse(res.data.value);
          if (res.data.type === "boolean") {
            // console.log("🚀 ~ handleOpen ~ retValue:", retValue);
            retValue = !!retValue;
          }
        }

        setValue(retValue);

        setOldValue(retValue);
        setOldType(res.data.type);

        setIsDataReady(true);
      }
    }
  };

  const handleOpenRef = useRef(handleOpen);
  handleOpenRef.current = handleOpen;

  const handleClose = () => {
    if (closeCallback) {
      closeCallback();
    }
    onClose();
  };

  useEffect(() => {
    if (visible) {
      handleOpenRef.current();
    }
  }, [visible]);

  const { isLoading, http } = useHttp();
  // const { id } = useGlobalState('user', 'userInfo')

  const handleConfirm = async () => {
    if (!name) {
      showToast("Please enter config name");
      return;
    }

    if (!introduce) {
      showToast("Please enter config description");
      return;
    }

    if (!type) {
      showToast("Please select config type");
      return;
    }

    const res = await http.post(
      isCreateMode ? "/api/config/create" : "/api/config/update",
      {
        ...(!isCreateMode ? { configid: configId } : {}),
        appid: appId,
        name,
        introduce,
        type,
        value,
        env,
      }
    );

    if (res?.success) {
      handleClose();
    }

    if (confirmCallback) {
      confirmCallback(res?.success);
    }
  };

  const typeList = [
    "string",
    "number",
    "boolean",
    "object",
    "array",
    "json",
  ] as const;

  const envList = ["all", "local", "development", "test", "production"];

  if (!isDataReady) {
    return null;
  }

  return (
    <div className="create-app-modal">
      {isCreateMode && (
        <Button
          size={triggerBtnSize}
          radius="md"
          color="primary"
          onClick={handleOpen}
        >
          {triggerBtnText || "Add"}
        </Button>
      )}
      <Modal size={size} isOpen={isOpen} onClose={handleClose}>
        <ModalContent>
          {(onClose) => (
            <>
              <ModalHeader className="flex flex-col gap-1">
                {isCreateMode ? "Create" : "Edit"} Config
              </ModalHeader>
              <ModalBody className="max-h-[600px] overflow-y-auto">
                <div className="config-modal-content flex flex-col gap-4">
                  <div className="control-line">
                    <Input
                      label="Name"
                      size="md"
                      labelPlacement="outside"
                      value={name}
                      onChange={(e) => setName(e.target.value)}
                      className="w-full"
                      isRequired
                      placeholder="Enter config name"
                    />
                  </div>
                  <div className="control-line">
                    <Textarea
                      labelPlacement="outside"
                      isRequired
                      label="Description"
                      placeholder="Enter config description"
                      className="w-full"
                      value={introduce}
                      onChange={(e) => setIntroduce(e.target.value)}
                    />
                  </div>
                  <div className="control-line">
                    <Select
                      labelPlacement="outside"
                      isRequired
                      size="md"
                      selectedKeys={[env]}
                      onChange={(e) => setEnv(e.target.value)}
                      className="w-full"
                      label="Environment"
                      placeholder="Select config env"
                    >
                      {envList.map((item) => (
                        <SelectItem key={item} value={item}>
                          {item}
                        </SelectItem>
                      ))}
                    </Select>
                  </div>
                  <div className="control-line">
                    <Select
                      labelPlacement="outside"
                      isRequired
                      size="md"
                      selectedKeys={[type]}
                      onChange={(e) => setType(e.target.value as FieldType)}
                      className="w-full"
                      label="Type"
                      placeholder="Select config type"
                    >
                      {typeList.map((item) => (
                        <SelectItem key={item} value={item}>
                          {item}
                        </SelectItem>
                      ))}
                    </Select>
                  </div>
                  <div className="control-line">
                    <ConfigValue
                      type={type}
                      onChange={updateValue}
                      initValue={type === oldType ? oldValue : undefined}
                    />
                  </div>
                </div>
              </ModalBody>
              <ModalFooter>
                <Button
                  isLoading={isLoading}
                  color="primary"
                  onPress={handleConfirm}
                >
                  {confirmBtnText ?? isCreateMode ? "Create" : "Save"}
                </Button>
                <Button color="primary" variant="flat" onPress={onClose}>
                  {cancelBtnText || "Cancel"}
                </Button>
              </ModalFooter>
            </>
          )}
        </ModalContent>
      </Modal>
    </div>
  );
};

export default ConfigModal;
